using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Rifts.Models
{
	public static class XElementExtensions
	{
		public static bool HasAttribute(this XElement element, string attributeName)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return false;
			else
				return !string.IsNullOrEmpty(attribute.Value);
		}

		public static string GetAttribute(this XElement element, string attributeName)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return null;
			else
				return attribute.Value;
		}

		public static T GetEnum<T>(this XElement element, string attributeName)
		{
			if (!typeof(T).IsEnum)
				throw new ArgumentException("The type " + typeof(T).FullName + " is not an Enum");

			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				throw new ArgumentException("Cannot find attribute " + attributeName + " on node " + element);
			else
				return (T)Enum.Parse(typeof(T), attribute.Value);
		}

		public static T GetEnum<T>(this XElement element, string attributeName, T defaultValue)
		{
			if (!typeof(T).IsEnum)
				throw new ArgumentException("The type " + typeof(T).FullName + " is not an Enum");

			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return defaultValue;
			else
				return (T)Enum.Parse(typeof(T), attribute.Value);
		}

		public static T? GetEnum2<T>(this XElement element, string attributeName) where T : struct
		{
			if (!typeof(T).IsEnum)
				throw new ArgumentException("The type " + typeof(T).FullName + " is not an Enum");

			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return null;
			else
				return (T)Enum.Parse(typeof(T), attribute.Value);
		}


		public static int GetInt(this XElement element, string attributeName)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				throw new ArgumentException("Cannot find attribute " + attributeName + " on node " + element);
			else
				return int.Parse(attribute.Value);
		}


		public static int GetInt(this XElement element, string attributeName, int defaultValue)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return defaultValue;
			else
				return int.Parse(attribute.Value);
		}

		public static IList<int> GetInts(this XElement element, string attributeName, int defaultValue)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return new int[] { defaultValue };
			else
				return (from s in  attribute.Value.Split(',') select int.Parse(s.Trim())).ToList();
		}


		public static bool GetBool(this XElement element, string attributeName)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return false;
			else
				return bool.Parse(attribute.Value);
		}

		public static bool GetBool(this XElement element, string attributeName, bool defaultValue)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return defaultValue;
			else
				return bool.Parse(attribute.Value);
		}

		public static int? GetInt2(this XElement element, string attributeName)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return null;
			else
				return int.Parse(attribute.Value);
		}

		public static int? ParseAttribute(this XElement element, string attributeName, Random random)
		{
			var attribute = element.Attribute(attributeName);
			if (attribute == null)
				return null;
			else
				return random.Parse(attribute.Value);
		}
	}
}
